﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Caliburn.Micro;
using System.Windows.Input;
using FlickrDownloadr.Services;
using FlickrNet;
using FlickrDownloadr.Features.Shell;
using Autofac;
using System.Collections.ObjectModel;
using System.Windows;

namespace FlickrDownloadr.Features.Search
{
    public enum SearchCategory
    {
        Photos,
        Groups,
        People
    }

    public class SearchViewModel : Screen
    {
        private string _searchText;
        private string _status;
        private IPhotoService _photoService;
        private IComponentContext _container;
        private IWindowManager _windowManager;

        public SearchViewModel(IPhotoService photoService, IComponentContext container, IWindowManager windowManager)
        {
            SearchCategory = SearchCategory.Photos;

            _photoService = photoService;
            _container = container;
            _windowManager = windowManager;

            PopulateItemCount();

            _numberPerPage = Properties.Settings.Default.NumberPerPage;
        }

        public SearchCategory SearchCategory { get; set; }


        public void PhotosRadio()
        {
            SearchCategory = SearchCategory.Photos;
        }

        public void GroupsRadio()
        {
            SearchCategory = SearchCategory.Groups;
        }

        public void PeopleRadio()
        {
            SearchCategory = SearchCategory.People;
        }

        public string SearchText
        {
            get { return _searchText; }
            set
            {
                if (value != _searchText)
                {
                    _searchText = value;
                    NotifyOfPropertyChange(() => SearchText);
                }
            }
        }

        public string Status
        {
            get { return _status; }
            set
            {
                if (value != _status)
                {
                    _status = value;
                    NotifyOfPropertyChange(() => Status);
                }
            }
        }

        private bool _isBusy = false;

        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                if (value != _isBusy)
                {
                    _isBusy = value;
                    NotifyOfPropertyChange(() => IsBusy);
                }
            }
        }

        public void Search()
        {
            Status = "Searching " + SearchCategory + " for " + SearchText + "...";

            var options = new FlickrNet.PhotoSearchOptions();
            options.Text = SearchText;
            options.Page = CurrentPage;
            options.PerPage = NumberPerPage;
            options.Extras = PhotoSearchExtras.All;

            IsBusy = true;

            _photoService.Search(options, SearchCompleted);
        }

        public void UpdatePreview()
        {
            var options = new FlickrNet.PhotoSearchOptions();
            options.Text = SearchText;
            options.Page = CurrentPage;
            options.PerPage = NumberPerPage;
            options.Extras = PhotoSearchExtras.All;

            IsBusy = true;

            _photoService.Search(options, UpdatePreviewCompleted);
        }

        private int _numberPerPage;

        public int NumberPerPage
        {
            get { return _numberPerPage; }
            set {
                if (value != _numberPerPage)
                {
                    _numberPerPage = value;
                    NotifyOfPropertyChange(() => NumberPerPage);

                    // Update the settings for the user.
                    Properties.Settings.Default.NumberPerPage = _numberPerPage;

                    UpdatePreview();
                }
            }
        }

        public void DisplayPhoto(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2)
            {
                Photo photo = sender as Photo;

                Viewer.ViewerViewModel view = new Viewer.ViewerViewModel(photo);
                _windowManager.Show(view);
            }

            //MessageBox.Show("Display!" + photo.OwnerName);
        }

        private void SearchCompleted(FlickrResult<PhotoCollection> result)
        {
            if (result.Error != null)
            {
                MessageBox.Show(result.ErrorCode + ": " + result.ErrorMessage);
                return;
            }

            Results = result.Result;
            IsBusy = false;
            Status = "Displaying results for " + SearchText + " (" + SearchCategory + ").";
            _container.Resolve<IShell>().CanGoForward = true;
            
            PopulatePages(Results.Pages);
            //CurrentPage = 1;
        }

        private void UpdatePreviewCompleted(FlickrResult<PhotoCollection> result)
        {
            if (result.Error != null)
            {
                MessageBox.Show(result.ErrorCode + ": " + result.ErrorMessage);
                return;
            }

            Results = result.Result;
            IsBusy = false;
            Status = "Displaying results for " + SearchText + " (" + SearchCategory + ").";
            _container.Resolve<IShell>().CanGoForward = true;

            // If the number of pages changes after the user changes index, we'll need to handle that...
            PopulatePages(Results.Pages);
        }

        private void PopulatePages(int count)
        {
            //if (count == Pages.Count) return;

            Pages.Clear();

            for (int i = 1; i < count + 1; i++)
            {
                Pages.Add(i);
            }

            NotifyOfPropertyChange(() => CurrentPage);
            NotifyOfPropertyChange(() => CanMoveNext);
            NotifyOfPropertyChange(() => CanMoveBack);
        }

        private int _thumbnailSize = 64;

        public int ThumbnailSize
        {
            get { return _thumbnailSize; }
            set
            {
                if (value != _thumbnailSize)
                {
                    _thumbnailSize = value;
                    NotifyOfPropertyChange(() => ThumbnailSize);
                }
            }
        }

        private void PopulateItemCount()
        {
            ItemCount.Clear();

            ItemCount.Add(5);
            ItemCount.Add(10);
            ItemCount.Add(20);
            ItemCount.Add(50);
            ItemCount.Add(100);
            ItemCount.Add(250);
            ItemCount.Add(500);

            // Set index to the first one.
            //NumberPerPage = 20;
        }

        private int _currentPage = 1;

        public int CurrentPage
        {
            get { return _currentPage; }
            set
            {
                if (value != _currentPage)
                {
                    _currentPage = value;
                    NotifyOfPropertyChange(() => CurrentPage);
                    NotifyOfPropertyChange(() => CanMoveBack);
                    NotifyOfPropertyChange(() => CanMoveNext);

                    UpdatePreview();
                }
            }
        }

        public bool CanMoveBack
        {
            get { return CurrentPage > 1; }
        }

        public void MoveBack()
        {
            CurrentPage--;
        }

        public bool CanMoveNext
        {
            get { return CurrentPage < Results.Pages; }
        }

        public void MoveNext()
        {
            CurrentPage++;
        }

        private ObservableCollection<int> _pages = new ObservableCollection<int>();

        public ObservableCollection<int> Pages
        {
            get { return _pages; }
        }

        private ObservableCollection<int> _itemCount = new ObservableCollection<int>();

        public ObservableCollection<int> ItemCount
        {
            get { return _itemCount; }
        }

        public bool DisplayPreviewNavigation
        {
            get { return (Results.Count > 0); }
        }

        private PhotoCollection _results = new PhotoCollection();

        public PhotoCollection Results
        {
            get { return _results; }
            set {
                _results = value;
                NotifyOfPropertyChange(() => Results);
                NotifyOfPropertyChange(() => DisplayPreviewNavigation);
            }
        }

        public void SearchKeyDown(System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                Search();
            }
        }
    }
}
